import os
import sys
import shutil
from datetime import datetime

# 全局变量，用于存储总文件数和当前处理的文件数
total_files = 0
processed_files = 0

def log_error(file_path, error_message):
    """
    将无法替换或替换出错的文件及其路径记录到文本文件中。

    :param file_path: 文件路径
    :param error_message: 错误信息
    """
    log_file_path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "replace_errors.txt")
    with open(log_file_path, "a", encoding="utf-8") as log_file:
        log_file.write(f"文件: {file_path}\n错误: {error_message}\n\n")
    print(f"已记录错误: {file_path} - {error_message}")

def replace_pwexcel_file(file_path, new_file_path):
    """
    替换指定路径下的PwExcel.exe文件。

    :param file_path: 目标文件路径
    :param new_file_path: 新文件路径
    """
    global processed_files
    try:
        # 检查目标文件是否存在
        if os.path.exists(file_path):

            # 替换文件
            shutil.copy(new_file_path, file_path)
            print(f"已替换文件: {file_path}")
        else:
            print(f"目标文件不存在: {file_path}")
            log_error(file_path, "目标文件不存在")
    except Exception as e:
        print(f"替换文件时出错: {file_path} - {str(e)}")
        log_error(file_path, str(e))
    finally:
        processed_files += 1
        update_progress()

def process_files_in_folder(folder_path, new_file_path):
    """
    递归查找文件夹中的所有PwExcel.exe文件并替换。

    :param folder_path: 文件夹路径
    :param new_file_path: 新文件路径
    """
    global total_files
    pwexcel_files = []

    # 首先收集所有PwExcel.exe文件
    for root, _, files in os.walk(folder_path):
        for filename in files:
            if filename.lower() == "pwexcel.exe":
                pwexcel_files.append(os.path.join(root, filename))

    total_files = len(pwexcel_files)
    print(f"共找到 {total_files} 个PwExcel.exe文件")

    # 替换每个文件
    for file_path in pwexcel_files:
        replace_pwexcel_file(file_path, new_file_path)

def update_progress():
    """
    更新并显示处理进度。
    """
    global processed_files, total_files
    if total_files > 0:
        progress = (processed_files / total_files) * 100
        print(f"\r处理进度: {processed_files}/{total_files} ({progress:.1f}%)", end="")
        if processed_files == total_files:
            print("\n处理完成!")

def is_network_path(path):
    """
    判断路径是否为网络路径。

    :param path: 路径
    :return: 是否为网络路径
    """
    return path.startswith("\\\\")

def check_network_path(path, timeout=10):
    """
    检查网络路径是否可访问。

    :param path: 网络路径
    :param timeout: 超时时间（秒）
    :return: 是否可访问
    """
    if not is_network_path(path):
        return False

    try:
        # 获取网络路径的主机名
        host = path.split("\\")[2]
        # 创建一个队列用于存储结果
        import queue
        result_queue = queue.Queue()

        # 定义一个函数用于检查主机是否可访问
        import threading
        def check_host():
            try:
                import socket
                socket.gethostbyname(host)
                result_queue.put(True)
            except socket.gaierror:
                result_queue.put(False)

        # 创建一个线程来检查主机
        thread = threading.Thread(target=check_host)
        thread.daemon = True
        thread.start()
        thread.join(timeout)

        # 如果线程仍在运行，说明超时
        if thread.is_alive():
            return False

        return result_queue.get() if not result_queue.empty() else False
    except Exception as e:
        print(f"检查网络路径 {path} 时出错: {str(e)}")
        return False

def main():
    # 获取新PwExcel.exe文件路径
    current_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
    new_file_path = os.path.join(current_dir, "PwExcel.exe")

    if not os.path.exists(new_file_path):
        print(f"新PwExcel.exe文件不存在: {new_file_path}")
        return

    # 检查是否有拖放的文件或文件夹
    if len(sys.argv) > 1:
        file_or_folder_path = sys.argv[1]
        if os.path.exists(file_or_folder_path):
            if os.path.isfile(file_or_folder_path) and os.path.basename(file_or_folder_path).lower() == "pwexcel.exe":
                replace_pwexcel_file(file_or_folder_path, new_file_path)
            elif os.path.isdir(file_or_folder_path):
                process_files_in_folder(file_or_folder_path, new_file_path)
            else:
                print("请拖放一个有效的PwExcel.exe文件或文件夹")
        else:
            # 检查是否为网络路径
            if is_network_path(file_or_folder_path):
                if check_network_path(file_or_folder_path):
                    if os.path.basename(file_or_folder_path).lower() == "pwexcel.exe":
                        replace_pwexcel_file(file_or_folder_path, new_file_path)
                    else:
                        process_files_in_folder(file_or_folder_path, new_file_path)
                else:
                    print(f"无法访问网络路径 {file_or_folder_path}")
            else:
                print("路径无效")
    else:
        print("请拖放一个PwExcel.exe文件或文件夹到此程序")

if __name__ == "__main__":
    main()
